#ifndef SCHEDULE_H
#define SCHEDULE_H

#include "myday.h"
#include "exporttable.h"
#include "memberclass.h"
#include "myscheduletable.h"

#include <QWidget>
#include <QStackedWidget>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QPushButton>

#define MINI_NIGHT_COUNT                (6) // 每人每月夜班最少数量
#define MAXI_NIGHT_COUNT               (8) // 每人每月夜班最多数量

#define MINI_NIGHTWORK_INTERVAL  (2) // 两个夜班之间的最小间隔
#define DEFAULT_NIGHTWORK_INTERVAL  (4) // 两个夜班之间的默认间隔

#define ALLOW_ROOKIE_FLAG   (0) //是否允许新人单独排班 0--不允许 1--允许

typedef struct _DataInMonth
{
    /* 班时相关 */
    int allWorkDay;                                     // 总工作日数量，即法定工作日数量 = workDayCount + specifyDayCount
    int allWorkTime;                                    // 总工作时数量，等于总工作日*总人数（除去新人的人数），白班算1个，夜班算2个
    int workDayCount;                               // 普通工作日的数量
    int holidayCount;                                   // 节假日的数量    holidayCount + allDay = 当月天数
    int specifyDayCountInWorkDay;        // 工作日统一监控日的数量
    int specifyDayCountInHolidayDay;        // 节假日统一监控日的数量
//    int specifyDayCount;        // 统一监控日的数量 = specifyDayCountInWorkDay + specifyDayCountInHolidayDay
//    int miniWorkDayRequireTime;      //  普通工作日最少需要班时数，= 白3夜3 * workDayCount
//    int maxiWorkDayRequireTime;     //  普通工作日最多需要班时数，= 白4夜3 * workDayCount
//    int miniHolidayRequireTime;      //  节假日最少需要班时数，=白2夜3 * holidayCount
//    int maxiHolidayRequireTime;     //  节假日最多需要班时数，=白3夜3 * holidayCount
//    int miniSpecialDayRequireTime;      //  统一监控最少需要班时数，=白3夜4 * specifyDayCount
//    int maxiSpecialDayRequireTime;     //  统一监控最多需要班时数，=白4夜4 * specifyDayCount
//    int miniRequireTime;      //  最少需要班时数，= miniWorkDayRequireTime + miniHolidayRequireTime + miniSpecialDayRequireTime
//    int maxiRequireTime;     //  最多需要班时数，= maxiWorkDayRequireTime + maxiHolidayRequireTime + maxiSpecialDayRequireTime
//    int allWorkDayTime;        // 普通工作日的班时数，=（白班 人数3-4+（夜班人数3）*2）*普通工作日天数
//    int allHolidayTime;           // 节假日的总班时数，=（（白班人数2-3）+（夜班人数3）*2）*节假日天数
//    int allSpecialDayTime;     // 统一监控的总班时数, =（（白班人数3-4）+（夜班人数4）*2）*统一监控天数
    int NightCountSum;                  // 当前夜班总数

    /* 成员相关 */
    int allMemberCount;                     // 成员总数 = rookieCount + commonMemberCount
    int rookieCount;                            // 新人数量
    int commonCount;                        // 非新人数量
}DataInMonth;

class Schedule : public QWidget
{
    Q_OBJECT
public:
    explicit Schedule(QWidget *parent = nullptr);
    explicit Schedule(QWidget *parent, QStackedWidget * pStackWidget);
    ~Schedule();

    void clearData(void);

private:
    void initScheduleTable(void);
template<class Type>
    void deleteBoxLayout(Type *t);
    void getMemberStringlist(const QList<MemberClass*> memberList);
    void getDayStringlist(const QList<myDay*> mydayList);
    void initSchedulePushButton(void);
    void fillData(void);
    void calcScheduleData(void);
    void fillPrivateList(void);
    void calcMember(void);
    void calcWorkTypeCount(void);
    void calcWorkTime(void);
    void startSchedule(void);
    void calcNeedWorkCount(void);
    void allocateDayWork(void);
    void rookieSchedule(void);
    void allocateNightWork(void);
    void allocateWorkToList(int & count, int type, int interval, int loop, myDay* & pDay, bool expectflag);
    int randSelectMember(QVector<int> & errorvec);
    int checkWorkInterval(const QVector<int> & vec, int day, int lowerlimit, int type);
    int checkNightCountAverage(int count);
    int addWorkToList(MemberClass *&pMember, myDay *&pDay, int type);
    int VerifyWorkToList(MemberClass *&pMember, myDay *&pDay, int type, int nightIntervall, bool expectflag);
    void changeMemberWithDateAction(void);
    void paintTable(void);
    void painteCentralTable(void);
    void paintDayAndNight(const QVector<int> & vec0, const QVector<int> & vec1, int col);
    void painteSpecialRow(void);
    void painteSpecialCol(void);
    void changeActionScheduleList(int row, int col);

signals:
    void signal_exportTableBtn_triggered(QList<MemberClass*> memberList, QList<myDay*> dayList);

public slots:
    void slot_Schedule_start(void);

private slots:
    void slot_btnRebuild_clicked(void);
    void slot_btnExport_clicked(void);
    void slot_btnReturn_clicked(void);
    void slot_changeScheduleWorkAction_triggered(QPoint pos, int type);

private:
    QWidget *myParent;
    QHBoxLayout *tableLayout;
    QHBoxLayout *btnLayout;
    QVBoxLayout *widgetLayout;
    QStackedWidget * pStackWidget;
    MyScheduleTable * pTable;
    ExportTable * pExport;
    QStringList memberNameList;
    QStringList dayStringList;
    QList<MemberClass*> memberList;
    QList<myDay*> dayList;
    DataInMonth *pDataInMonth;
    int specialColumnStart;
    int specialColumnCount;
    int specialRowStart;
    int specialRowCount;
};

#endif // SCHEDULE_H
